package pl.us.ij.plugins.segmentation.commands;

public final class MatrixHelper {

    public static int[][] intZeros(int dimSize) {
        if (dimSize < 0)
            throw new IllegalArgumentException("dimSize param must be greater than 0.");
        if (dimSize > 99)
            throw new IllegalArgumentException("dimSize param must be less than 100.");

        int[][] matrix = new int[dimSize][dimSize];

        return intInitialize(matrix, 0);
    }

    public static int[][] intOnes(int dimSize) {
        if (dimSize < 0)
            throw new IllegalArgumentException("dimSize param must be greater than 0.");
        if (dimSize > 99)
            throw new IllegalArgumentException("dimSize param must be less than 100.");

        int[][] matrix = new int[dimSize][dimSize];

        return intInitialize(matrix, 1);
    }

    public static int intSum(int[][] matrix) {
        int sum = 0;

        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix.length; j++)
                sum += matrix[i][j];

        return sum;
    }

    public static int[][] intMultiply(int[][] m1, int[][] m2) {

        int[][] m = intZeros(m1.length);

        for (int i = 0; i < m1.length; i++)
            for (int j = 0; j < m1.length; j++)
                m[i][j] = m1[i][j] * m2[i][j];

        return m;
    }

    private static int[][] intInitialize(int[][] matrix, int value) {

        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix.length; j++)
                matrix[i][j] = value;

        return matrix;
    }

    public static double[][] doubleZeros(int dimSize) {
        if (dimSize < 0)
            throw new IllegalArgumentException("dimSize param must be greater than 0.");
        if (dimSize > 99)
            throw new IllegalArgumentException("dimSize param must be less than 100.");

        double[][] matrix = new double[dimSize][dimSize];

        return doubleInitialize(matrix, 0);
    }

    public static double[][] doubleOnes(int dimSize) {
        if (dimSize < 0)
            throw new IllegalArgumentException("dimSize param must be greater than 0.");
        if (dimSize > 99)
            throw new IllegalArgumentException("dimSize param must be less than 100.");

        double[][] matrix = new double[dimSize][dimSize];

        return doubleInitialize(matrix, 1);
    }

    public static double doubleSum(double[][] matrix) {
        double sum = 0;

        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix.length; j++)
                sum += matrix[i][j];

        return sum;
    }

    public static double[][] doubleMultiply(double[][] m1, double[][] m2) {

        double[][] m = doubleZeros(m1.length);

        for (int i = 0; i < m1.length; i++)
            for (int j = 0; j < m1.length; j++)
                m[i][j] = m1[i][j] * m2[i][j];

        return m;
    }

    private static double[][] doubleInitialize(double[][] matrix, double value) {

        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix.length; j++)
                matrix[i][j] = value;

        return matrix;
    }

    public static float[][] floatZeros(int dimSize) {
        if (dimSize < 0)
            throw new IllegalArgumentException("dimSize param must be greater than 0.");
        if (dimSize > 99)
            throw new IllegalArgumentException("dimSize param must be less than 100.");

        float[][] matrix = new float[dimSize][dimSize];

        return floatInitialize(matrix, 0);
    }

    public static float[][] floatOnes(int dimSize) {
        if (dimSize < 0)
            throw new IllegalArgumentException("dimSize param must be greater than 0.");
        if (dimSize > 99)
            throw new IllegalArgumentException("dimSize param must be less than 100.");

        float[][] matrix = new float[dimSize][dimSize];

        return floatInitialize(matrix, 1);
    }

    public static float floatSum(float[][] matrix) {
        float sum = 0;

        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix.length; j++)
                sum += matrix[i][j];

        return sum;
    }

    public static float[][] floatMultiply(float[][] m1, float[][] m2) {

        float[][] m = floatZeros(m1.length);

        for (int i = 0; i < m1.length; i++)
            for (int j = 0; j < m1.length; j++)
                m[i][j] = m1[i][j] * m2[i][j];

        return m;
    }

    private static float[][] floatInitialize(float[][] matrix, float value) {

        for (int i = 0; i < matrix.length; i++)
            for (int j = 0; j < matrix.length; j++)
                matrix[i][j] = value;

        return matrix;
    }

    public static float[][] floatMatrix(int dimSize, float... values) {

        if (values.length != dimSize * dimSize)
            throw new IllegalArgumentException("Wrong number of initialization arguments");

        float[][] matrix = floatZeros(dimSize);

        int x = 0;
        int y = 0;
        for (float v : values) {
            matrix[y][x] = v;
            x++;

            if (x == dimSize) {
                x = 0;
                y++;
            }
        }

        return matrix;
    }
}
